/*
 * PidginCote
 * ===========
 *	Syncs your chatlogs with Google Docs.
 *
 *	Development blog:
 *	http://pidgincote.artillery.be/
 *
 *	Code project:
 *	http://code.google.com/p/pidgincote/
 */


// Define the version number:
#define CS_VERSION "0.0.1"

// Load config:
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

/* config.h may define PURPLE_PLUGINS; protect the definition here so that we
 * don't get complaints about redefinition when it's not necessary. */
#ifndef PURPLE_PLUGINS
# define PURPLE_PLUGINS
#endif

/* This will prevent compiler errors in some instances and is better explained in the
 * how-to documents on the wiki */
#ifndef G_GNUC_NULL_TERMINATED
# if __GNUC__ >= 4
#  define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
# else
#  define G_GNUC_NULL_TERMINATED
# endif
#endif

// =========================================================================================================================================
// Library includes
// =========================================================================================================================================

// SQLite:
#include "PidginCote/sqlite3.c"

// GLib:
#include <glib.h>
#include <glib/gstdio.h>

// Purple:
#include <notify.h>
#include <plugin.h>
#include <version.h>
#include <string.h>
#include <debug.h>
#include <blist.h>
#include <conversation.h>

// Pidgin:
#include <gtkutils.h>
#include <gtkplugin.h>
#include <gtkprefs.h>



// =========================================================================================================================================
// PidginCote includes
// =========================================================================================================================================
// Headers:
#include "PidginCote/Events.h"
#include "PidginCote/HTTPRequest.h"
#include "PidginCote/HTTPResponse.h"
#include "PidginCote/NetClient.h"
#include "PidginCote/Log.h"
#include "PidginCote/LogDatabase.h"
#include "PidginCote/Utilities.h"
#include "PidginCote/UserInterface.h"
#include "PidginCote/DBTable_Accounts.h"
#include "PidginCote/DBTable_Logs.h"
#include "PidginCote/Log_Mini.h"
#include "PidginCote/Sync.h"

// Source:
#include "PidginCote/Events.c"
#include "PidginCote/HTTPRequest.c"
#include "PidginCote/HTTPResponse.c"
#include "PidginCote/NetClient.c"
#include "PidginCote/Log.c"
#include "PidginCote/LogDatabase.c"
#include "PidginCote/Utilities.c"
#include "PidginCote/UserInterface.c"
#include "PidginCote/DBTable_Accounts.c"
#include "PidginCote/DBTable_Logs.c"
#include "PidginCote/Log_Mini.c"
#include "PidginCote/Sync.c"

// TODO: Set up automake.

// =========================================================================================================================================
// Pidgin-specific functions:
// =========================================================================================================================================

/**
 * This is called when the plugin is initialized (i.e. Toggled via the plugins list)
 */
static void init_plugin(PurplePlugin *plugin) {
	purple_debug(PURPLE_DEBUG_INFO, "PidginCote", "Initialization\r\n");

	// Init prefs:
    purple_prefs_add_none("/plugins/gtk/gtk-dephille-pidgincote");
    purple_prefs_add_string("/plugins/gtk/gtk-dephille-pidgincote/auth", "");

	//	pidgincote_plugin = plugin; TODO: Check if necessary
}


/**
 * Called when the plugin was activated and loaded. (i.e. Every time pidgin is started and the plugin is activated).
 */
static gboolean plugin_load(PurplePlugin *plugin) {
	gboolean dummy;	// Clean-up: No

	purple_debug(PURPLE_DEBUG_INFO, "PidginCote", "Loading\r\n");

	// Init parts:
	PC_Net_Init();
	PC_LogDB_Init();

	// Init by starting some events:
	dummy = PC_Event_ScanActiveAccounts(NULL);

	// Schedule events:
	purple_timeout_add_seconds(3, PC_Event_Login, NULL);
	purple_timeout_add_seconds(30, PC_Event_ScanActiveAccounts, NULL);
	purple_timeout_add_seconds(10, PC_Event_SyncLogList, NULL);

	// Connect signals:
	purple_signal_connect(purple_accounts_get_handle(), "account-signed-on", plugin, PURPLE_CALLBACK(PC_Sync_FS), NULL);

	// Return success:
	return TRUE;
}

/**
 * Called when the plugin is stopped. (By either closing pidgin or deactivating the plugin from the plugin list)
 */
static gboolean plugin_unload(PurplePlugin *plugin) {
	purple_debug(PURPLE_DEBUG_INFO, "PidginCote", "Unloading\r\n");

	// Uninit parts:
	PC_LogDB_Uninit();

	// Return success:
	return TRUE;
}




/**
 * Config frame
 */
static PidginPluginUiInfo ui_info = {
		PC_UI_Load,
        0,
        NULL,
        NULL,
        NULL,
        NULL
};



// =========================================================================================================================================
// Plugin identification:
// =========================================================================================================================================
static PurplePluginInfo info = {
    PURPLE_PLUGIN_MAGIC,    /* Plugin magic, this must always be
                               PURPLE_PLUGIN_MAGIC.*/

    PURPLE_MAJOR_VERSION,   /* This is also defined in libpurple.  It helps
                               libpurple's plugin system determine which version
                               of libpurple this plugin was compiled for, and
                               whether loading it will cause problems. */

    PURPLE_MINOR_VERSION,   /* See previous */

    PURPLE_PLUGIN_STANDARD, /* PurplePluginType: There are 4 different values for
                               this field.  The first is PURPLE_PLUGIN_UNKNOWN,
                               which should not be used.  The second is
                               PURPLE_PLUGIN_STANDARD; this is the value most
                               plugins will use. Next, we have PURPLE_PLUGIN_LOADER;
                               this is the type you want to use if your plugin will
                               make it possible to load non-native plugins.  For
                               example, the Perl and Tcl loader plugins are of this
                               type.  Last, we have PURPLE_PLUGIN_PROTOCOL.  If your
                               plugin is going to allow the user to connect to
                               another network, this is the type you'd want to use. */

    PIDGIN_PLUGIN_TYPE,                   /* This field is the UI requirement.  If you're writing
                               a core plugin, this must be NULL and the plugin must
                               not contain any UI code.  If you're writing a Pidgin
                               plugin, you need to use PIDGIN_PLUGIN_TYPE.  If you
                               are writing a Finch plugin, you would use
                               FINCH_PLUGIN_TYPE.*/

    0,                      /* This field is for plugin flags.  Currently, the only
                               flag available to plugins is invisible
                               (PURPLE_PLUGIN_FLAG_INVISIBLE). It causes the plugin
                               NOT to appear in the list of plugins. */

    NULL,                   /* This is a GList of plugin dependencies.  In other words,
                               it's a GList of plugin id's that your plugin depends on.
                               Set this value to NULL no matter what.  If your plugin
                               has dependencies, set them at run-time in the
                               plugin_init function. */

    PURPLE_PRIORITY_DEFAULT,/* This is the priority libpurple will give your plugin.
                               There are three possible values for this field,
                               PURPLE_PRIORITY_DEFAULT, PURPLE_PRIORITY_HIGHEST, and
                               PURPLE_PRIORITY_LOWEST. */

    "gtk-dephille-pidgincote",/* This is your plugin's id.  There is a whole page dedicated
                               to this in the Related Pages section of the API docs. */

    "PidginCote Chatlog Synchronisation",/* This is your plugin's name.  This is what will be
                               displayed for your plugin in the UI. */

    CS_VERSION,             /* This is the version of your plugin. */

    "Chatlog Synchronisation with Google Docs for pidgin",/* This is the summary of your plugin.  It should be a short
                               blurb.  The UI determines where, if at all, to display
                               this. */

    "Synchronizes your chatlogs with Google Docs.",/* This is the description of your plugin. It can be as long
                               and as descriptive as you like.  And like the summary,
                               it's up to the UI where, if at all, to display this (and
                               how much to display). */

    "DePhille <DePhille@gmail.com>", /* This is where you can put your name and e-mail
                                         address. */

    "http://dephille-compaq.hopto.org:8080/eindwerk/",/* This is the website for the plugin.  This tells users
                               where to find new versions, report bugs, etc. */

    plugin_load,            /* This is a pointer to a function for libpurple to call when
                               it is loading the plugin.  It should be of the type:

                                  gboolean plugin_load(PurplePlugin *plugin)

                               Returning FALSE will stop the loading of the plugin.
                               Anything else would evaluate as TRUE and the plugin will
                               continue to load. */

    plugin_unload,          /* Same as above except it is called when libpurple tries to
                               unload your plugin.  It should be of the type:

                                  gboolean plugin_unload(PurplePlugin *plugin)

                               Returning TRUE will tell libpurple to continue unloading
                               while FALSE will stop the unloading of your plugin. */

    NULL,                   /* Similar to the two above members, except this is called
                               when libpurple tries to destory the plugin.  This is
                               generally only called when for some reason or another the
                               plugin fails to probe correctly.  It should be of the type:

                                  void plugin_destroy(PurplePlugin *plugin) */

    &ui_info,                   /* This is a pointer to a UI-specific struct.  For a Pidgin
                               plugin it will be a pointer to a PidginPluginUiInfo
                               struct, for example. */

    NULL,                   /* This is a pointer to either a PurplePluginLoaderInfo
                               struct or a PurplePluginProtocolInfo struct, and is
                               beyond the scope of this document. */

    NULL,                   /* This is a pointer to a PurplePluginUiInfo struct.  It is
                               a core/ui split way for core plugins to have a UI
                               configuration frame.  You can find an example of this
                               code in libpurple/plugins/pluginpref_example.c */

    NULL,               /* This is a function pointer where you can define "plugin
                               actions".  The UI controls how they're displayed.  It
                               should be of the type:

                                  GList *function_name(PurplePlugin *plugin,
                                                       gpointer context)

                               It must return a GList of PurplePluginActions. */

    NULL,                   /* This is a pointer reserved for future use.  We set it to
                               NULL to indicate we don't need it. */

    NULL,                   /* This is a pointer reserved for future use.  We set it to
                               NULL to indicate we don't need it. */

    NULL,                   /* This is a pointer reserved for future use.  We set it to
                               NULL to indicate we don't need it. */

    NULL                    /* This is a pointer reserved for future use.  We set it to
                               NULL to indicate we don't need it. */
};

PURPLE_INIT_PLUGIN(PidginCote, init_plugin, info);
